#
# Generic rules to build file types from other file types and other
# common functionaly that is needed to build library or program targets.
#

#
# Collect object files and avoid duplicates (by using 'sort')
#
SRC_O   = $(addprefix binary_,$(addsuffix .o,$(notdir $(SRC_BIN))))
SRC     = $(sort $(SRC_C) $(SRC_CC) $(SRC_S) $(SRC_O))
OBJECTS = $(addprefix $(OBJ_PREFIX), $(addsuffix .o,$(basename $(SRC))))

#
# Make sure, that we rebuild object files after Makefile changes
#
$(wildcard $(OBJECTS)): $(filter-out $(LIB_PROGRESS_LOG),$(MAKEFILE_LIST))

INCLUDES = $(addprefix -I,$(ALL_INC_DIR))

#
# Include dependency files for the corresponding object files
#
-include $(OBJECTS:.o=.d)

$(OBJ_PREFIX)%.o: %.c
	$(MSG_COMP)$@
	$(VERBOSE)$(CC) $(CC_DEF) $(CC_C_OPT) $(INCLUDES) -c $< -o $@

$(OBJ_PREFIX)%.o: %.cc
	$(MSG_COMP)$@
	$(VERBOSE)$(CXX) $(CXX_DEF) $(CC_CXX_OPT) $(INCLUDES) -c $< -o $@

$(OBJ_PREFIX)%.o: %.cpp
	$(MSG_COMP)$@
	$(VERBOSE)$(CXX) $(CXX_DEF) $(CC_CXX_OPT) $(INCLUDES) -c $< -o $@

$(OBJ_PREFIX)%.o: %.s
	$(MSG_ASSEM)$@
	$(VERBOSE)$(AS) $(AS_OPT) $(INCLUDES) $< -o $@

#
# Assembler files that must be preprocessed are fed to the C compiler.
#
$(OBJ_PREFIX)%.o: %.S
	$(MSG_COMP)$@
	$(VERBOSE)$(CC) $(CC_DEF) $(CC_OPT) -D__ASSEMBLY__ $(INCLUDES) -c $< -o $@

#
# Link binary data
#
# We transform binary data into an object file by using the 'incbin' directive
# of the GNU assembler. This enables us to choose a any label for the binary
# data (in contrast to 'ld -r -oformat default -b binary', which generates the
# label from the input path name) and to align the binary data as required on
# some architectures (e.g., ARM).
#
symbol_name = _binary_$(subst -,_,$(subst .,_,$(subst $(OBJ_PREFIX)binary_,,$(subst .o,,$(notdir $@)))))

$(OBJ_PREFIX)binary_%.o: %
	$(MSG_CONVERT)$@
	$(VERBOSE)echo ".global $(symbol_name)_start; .data; .align 4; $(symbol_name)_start:; .incbin \"$<\"" |\
		$(AS) -f -o $@ -
